#include "Human.h"

Human::Human(btDiscreteDynamicsWorld* pWorld,
             btCylinderShape* pHumanCollisionShape,
             Ogre::SceneManager* pSceneManager,
             OpenSteer::Vec3 position) :
  Character::Character(pWorld, pHumanCollisionShape, pSceneManager,
                       position, HUMANMESH) {

  // Camara
  _pNode->attachObject(_pSceneManager->getCamera("MainCamera"));

  // Query mask
  _pEntity->setQueryFlags(QUERY_MASK_HUMAN);

  // AnimationState
  Ogre::AnimationState* humanAnimation =
    _pEntity->getAnimationState("Walk");
  humanAnimation->setEnabled(true);
  humanAnimation->setLoop(true);
  humanAnimation->setTimePosition(0.0);

  // Ataques
  _attackCounter = 0;

  // Character
  setLife(10);

  // Generador de nombres para sistemas de particulas de sangre
  _pBloodNameGenerator = new Ogre::NameGenerator("blood");
}

Human::~Human() {

  delete _pBloodNameGenerator;
}

void
Human::update(const float currentTime, const float elapsedTime) {

  // Orientar respecto a su vector dirección
  // Obtener vector dirección en Ogre
  Ogre::Vector3 ogreDirection(forward().x, forward().y, -forward().z);

  // Obtener cuaternio de rotación
  Ogre::Quaternion ogreRotation =
    ogreDirection.getRotationTo(Ogre::Vector3::NEGATIVE_UNIT_Z);

  // Convertir a cuaternio bullet
  btQuaternion bulletRotation(ogreRotation.x,
                              ogreRotation.y,
                              ogreRotation.z,
                              ogreRotation.w);

  // Obtener matriz de transformación con la nueva rotación
  btTransform bulletTransform(bulletRotation,
                              _pRigidBody->getCenterOfMassPosition());

  // Aplicar nueva transformación
  _pRigidBody->activate();
  _pRigidBody->setCenterOfMassTransform(bulletTransform);

  // Animar el humano
  _pEntity->getAnimationState("Walk")->addTime(elapsedTime);

  // Eliminar fuerzas
  _pRigidBody->clearForces();

  // Eliminar velocidad
  _pRigidBody->setLinearVelocity(btVector3(0, 0, 0));

  // Decrementar contador ataque
  if (_attackCounter > 0)
    _attackCounter -= elapsedTime;
}

void
Human::translate(btVector3 translation) {

  _pRigidBody->activate();
  _pRigidBody->translate(translation);
}

void Human::lookAt(Ogre::Vector3 targetPoint) {

  Ogre::Vector3 ogrePosition(position().x, 0, position().z);
  targetPoint.y = 0;
  Ogre::Vector3 ogreForward = targetPoint - ogrePosition;

  if (ogreForward.length() > 0) {

    OpenSteer::Vec3 steerForward(ogreForward.x, 0, ogreForward.z);
    regenerateOrthonormalBasis(steerForward);
  }
}

bool
Human::doDamage(int damage) {

  if (_attackCounter > 0) return false;

  _attackCounter = 2;

  _life = _life - damage;

  std::cout << "Life remaining " << _life << std::endl;

  Ogre::ParticleSystem* ps =
    _pSceneManager->createParticleSystem
    (_pBloodNameGenerator->generate(),
     "blood");
  _pNode->attachObject(ps);

  if (_life <= 0) {

    doDead();
    return true;
  }

  return false;
}
